//
//  XSAppleManager.m
//  AppleSignIn
//
//  Created by xingshuai on 2021/8/31.
//

#import "XSAppleManager.h"

/// ASAuthorizationControllerDelegate 处理数据回调
/// ASAuthorizationControllerPresentationContextProviding 设置上下文，管理视图弹出在哪里
@interface XSAppleManager () <ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding>

@end

@implementation XSAppleManager

static XSAppleManager *sharedHandle = nil;
/// 单例
+ (XSAppleManager *)sharedManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
        sharedHandle = [[XSAppleManager alloc] init];
    });
    return sharedHandle;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedHandle = [super allocWithZone:zone];
    });
    return sharedHandle;
}

- (id)copyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE {
    return sharedHandle;
}

- (id)mutableCopyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE {
    return sharedHandle;
}

/// 处理登录授权
- (void)handleAuthorizationAppleIDButtonLogin API_AVAILABLE(ios(13.0)) {
    // 基于用户的Apple ID授权用户，生成用户授权请求的一种机制
    ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
    // 创建新的AppleID 授权请求
    ASAuthorizationAppleIDRequest *appleIDRequest = [appleIDProvider createRequest];
    // 在用户授权期间请求的联系信息
    appleIDRequest.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
    // 由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器
    ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[appleIDRequest]];
    // 设置授权控制器通知授权请求的成功与失败的代理
    authorizationController.delegate = self;
    // 设置提供 展示上下文的代理，在这个上下文中 系统可以展示授权界面给用户
    authorizationController.presentationContextProvider = self;
    // 在控制器初始化期间启动授权流
    [authorizationController performRequests];
}

/// 用于展示在哪里
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller  API_AVAILABLE(ios(13.0)){
    return [UIApplication sharedApplication].windows.lastObject;
}

-(void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization  API_AVAILABLE(ios(13.0)){
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        ASAuthorizationAppleIDCredential *credential = authorization.credential;
        
        NSString *state = credential.state;
        NSString *user = credential.user;
        NSPersonNameComponents *fullName = credential.fullName;
        NSString *email = credential.email;
        NSString *authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding];
        NSString *identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];
        ASUserDetectionStatus realUserStatus = credential.realUserStatus;
        
        // 验证信息状态
        NSLog(@"state: %@", state);
        // 苹果用户唯一标识符
        NSLog(@"user: %@", user);
        // 用户共享的可选全名
        NSLog(@"fullName: %@", fullName);
        // 用户共享的可选电子邮件
        NSLog(@"email: %@", email);
        // 验证数据
        NSLog(@"authorizationCode: %@", authorizationCode);
        // Web令牌(JWT)
        NSLog(@"identityToken: %@", identityToken);
        // 标识用户是否为真实的人 unsupported（0)：当前平台不支持，忽略该值；unknown (1)：无法确认；likelyReal (2)：用户真实性非常高
        NSLog(@"realUserStatus: %@", @(realUserStatus));
                
        // fullName 包含内容
        /**
        namePrefix    String    名字前缀，头衔、敬称
        givenName     String    名字
        middleName    String    中间名
        familyName    String    姓
        nameSuffix    String    名字后缀，学位、荣誉
        nickName      String    昵称
         */
        
        // 将用到的数据传给后台去验证 （identityToken, authorizationCode, userID）
        
    } else if([authorization.credential isKindOfClass:ASPasswordCredential.class]) {
        // 这个获取的是iCloud记录的账号密码，需要输入框支持iOS 12 记录账号密码的新特性，如果不支持，可以忽略
        // Sign in using an existing iCloud Keychain credential.
        // 用户登录使用现有的密码凭证
        ASPasswordCredential *credential = authorization.credential;
        NSLog(@"user:%@", credential.user);
        NSLog(@"password:%@", credential.password);
    } else {
        NSLog(@"授权信息均不符");
    }
}

// 授权失败的回调
-(void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) {
    NSString *errorMsg = nil;
    switch (error.code) {
        case ASAuthorizationErrorCanceled:
            errorMsg = @"您已取消授权请求";
            break;
        case ASAuthorizationErrorFailed:
            errorMsg = @"授权请求失败";
            break;
        case ASAuthorizationErrorInvalidResponse:
            errorMsg = @"授权请求响应无效";
            break;
        case ASAuthorizationErrorNotHandled:
            errorMsg = @"未能处理授权请求";
            break;
        case ASAuthorizationErrorUnknown:
            errorMsg = @"授权请求失败未知原因";
            break;
        default:
            break;
    }
    NSLog(@"errorMsg = %@",errorMsg);
}

@end
